﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using SharedLib.Helpers;
using SharedLib.DataStructure;

namespace SharedLib.XmlDataModel
{
    /// <summary>
    /// Based on SerializableXmlDataModel, implemented interface IWithAttributes
    /// <para>Dictionary "Attributes" will be serialized to Xml Attributes of the root node</para>
    /// <para>Dictionary "Properties" will be serialized to the root node's child Xml Elements with single text node</para>
    /// </summary>
    /// <seealso cref="SerializableXmlDataModel"/>
    /// <seealso cref="IWithAttributes"/>
    [Serializable]
    public abstract class XmlDataModelWithAttributes : SerializableXmlDataModel, IWithAttributes
    {
        #region Constructors
        protected XmlDataModelWithAttributes():base(){}
        protected XmlDataModelWithAttributes(XmlNode node):base(node){}
        #endregion

        /// <summary>
        /// Build dictionary from Xml source
        /// </summary>
        /// <param name="rootNode">Xml root node</param>
        protected override void ParseRootNode(XmlElement rootNode)
        {
            base.ParseRootNode(rootNode);
            Attributes.Clear();
            Properties.Clear();
            //Parse Xml Attributes
            foreach (XmlAttribute attr in rootNode.Attributes)
            {
                Attributes.Add(attr.Name, attr.Value);
            }

            //Parse child Xml Elements with single text node
            foreach (XmlNode childNode in rootNode.ChildNodes)
            {
                if (childNode is XmlElement)
                {
                    string value = XmlHelper.GetNodeValue(childNode);
                    if (value != null)
                    {
                        Properties.Add(childNode.Name, value);
                    }
                }
            }
        }
        /// <summary>
        /// Generate Xml node according to dictionaries
        /// </summary>
        /// <param name="doc">Xml document of the exporting node</param>
        /// <returns>Generated Xml node</returns>
        protected override XmlElement GenerateXmlNode(XmlDocument doc)
        {
            XmlElement rootNode = base.GenerateXmlNode(doc);
            foreach (string key in Attributes.Keys)
            {
                rootNode.SetAttribute(key, Attributes[key]);
            }
            foreach (string key in Properties.Keys)
            {
                XmlElement childNode = doc.CreateElement(key);
                childNode.AppendChild(doc.CreateTextNode(Properties[key]));
                rootNode.AppendChild(childNode);
            }

            return rootNode;
        }

        #region IWithAttributes Members
        protected StringDictionaryWithKeys _attributes;
        protected StringDictionaryWithKeys _properties;
        /// <summary>
        /// Get "Attributes" dictionary
        /// </summary>
        public StringDictionaryWithKeys Attributes
        {
            get
            {
                if (_attributes == null)
                {
                    _attributes = new StringDictionaryWithKeys();
                }
                return _attributes;
            }
        }

        /// <summary>
        /// Get "Properties" dictionary
        /// </summary>
        public StringDictionaryWithKeys Properties
        {
            get
            {
                if (_properties == null)
                {
                    _properties = new StringDictionaryWithKeys();
                }
                return _properties;
            }
        }
        #endregion
    }
}
